#include "Alice/Graphs/ClipTextureRenderer.h"
#include "Alice/Log/Log.h"

namespace Alice
{

void ClipTextureRenderer::Init()
{
    glGenVertexArrays(1, &m_VAO);
    glGenBuffers(1, &m_VBO);

    m_shader.Use();
    m_shader.SetInt("image", 0);
    glm::mat4 projection = glm::ortho(0.0f, 800.f, 600.f, 0.0f, -1.0f, 1.0f);
    m_shader.SetMat44("projection", projection);
}

void ClipTextureRenderer::Render(
    Texture2D* texture,
    glm::vec2& position,
    glm::vec2& size,
    float rotate,
    glm::vec3& color,
    int width,
    int height,
    int frame_num
)
{
    // 精灵图总行数
    int row_num = texture->height / height;
    // 精灵图总列数
    int col_num = texture->width / width;

    // 求出纹理精灵所在行列
    int sprite_row, sprite_col;
    if (frame_num % col_num == 0)
    {
        // 纹理处于最后一列的情况
        sprite_row = frame_num / col_num - 1;
        sprite_col = col_num - 1;
    }
    else
    {
        sprite_row = frame_num / col_num;
        sprite_col = frame_num % col_num - 1;
    }

    // 根据行列求出对应的未标准化纹理坐标（左上角）
    float frame_num_x = sprite_col * width;
    float frame_num_y = sprite_row * height;
    
    // 计算一个裁切单位标准化后的尺寸
    float unit_width = (float)width / texture->width;
    float unit_height = (float)height / texture->height;
    // 计算被裁切的四个顶点的标准化坐标
    float left_top_x = frame_num_x / texture->width;
    float left_top_y = frame_num_y / texture->height;

    float right_top_x = left_top_x + unit_width;
    float right_top_y = left_top_y;
    
    float left_bottom_x  = left_top_x;
    float left_bottom_y = left_top_y + unit_height;

    float right_bottom_x = left_top_x + unit_width;
    float right_bottom_y = left_top_y + unit_height;

    float vertices[] = {
        0.0f, 1.0f, left_bottom_x, left_bottom_y,
        1.0f, 0.0f, right_top_x, right_top_y,
        0.0f, 0.0f, left_top_x, left_top_y, 

        0.0f, 1.0f, left_bottom_x, left_bottom_y,
        1.0f, 1.0f, right_bottom_x, right_bottom_y,
        1.0f, 0.0f, right_top_x, right_top_y
    };

    glBindVertexArray(m_VAO);

    glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (float*)0);

    // 渲染
    m_shader.Use();

    glm::mat4 model = glm::mat4(1.0f);

    model = glm::translate(model, glm::vec3(position, 0.0f));  

    model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); 
    model = glm::rotate(model, rotate, glm::vec3(0.0f, 0.0f, 1.0f)); 
    model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f));

    model = glm::scale(model, glm::vec3(size, 1.0f));

    m_shader.SetMat44("model", model);
    m_shader.SetVec3f("spriteColor", color);

    glActiveTexture(GL_TEXTURE0);
    texture->Bind();

    glDrawArrays(GL_TRIANGLES, 0, 6);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void ClipTextureRenderer::Destroy()
{
    glDeleteVertexArrays(1, &m_VAO);
    glDeleteBuffers(1, &m_VBO);
}

}
